/***************************************************************************
 *   Copyright (C) 2010 by Oleg Goncharov  *
 *   $EMAIL$                           *                          
 *                                                                         *
 *   This file is part of ChessVision.                                     *
 *                                                                         *
 *   ChessVision is free software; you can redistribute it and/or modify   *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef CCAMTRANSFORM_H
#define CCAMTRANSFORM_H


#include "../error/cerror.h"
#include "geomtypes.h"

#include "cimagesource.h"

using namespace cv;

/**
Преобразование координат 3D <-> изображение


	@author Goncharov Oleg <goncharovoi@yandex.ru>
*/

class CCamTransform {
    Mat_<double> intrinsic;
    Mat_<double> distortion;
    Mat_<double> rot_vect;
    Mat_<double> trans_vect;
    Mat_<double> rot_mat;


    vector<Point2f> i_points;
    vector<Point3f> o_points;
    int history_length;

    void Reserve();
public:
    CCamTransform();
    CCamTransform(const string& file); 
    
    ~CCamTransform();
    
    
    bool CalibrateIntrisictParams(CImageSource& src, cv::Size pattern_size, double square_side, bool calc_distortion = true);
    
    void SaveIntrinsicParams(const string& file) const;
    void LoadIntrinsicParams(const string& file);
    
    void SaveTransform(const string& file) const;
    void LoadTransform(const string& file);

    inline void AddPair(const Point2f& img, const Point3f& obj);
    inline void DelPair();
    inline void NewPair(const Point2f& img, const Point3f& obj);
    inline void ClearPairs();

    inline void SetHistoryLength(int len);

    void CalcTransform();
    bool RecalcTransform();

    Point2f ProjectPoint(const Point3f& obj) const;
    Point3f ReverseProjection(const Point2f& img, const HPlane3f& plane) const;

    void RemoveDistortion(const Mat& src, Mat& dst) const;

    void PrintIParams() const;
    void PrintTParams() const;
    
    HPlane3f		ToCameraCoord(const HPlane3f& plane) const;
    Mat_<double> 	getIntrinsicMat() const;
    Mat_<double> 	getReverseIntrinsicMat() const;
    Mat			getRemovePerspectiveMat() const;
};

#endif

